package geo.ani;

import geo.math.GMath;
import geo.obj.Domain;
import geo.obj.PhiObject;
import gui.panels.DomainDrawPanel;

import java.awt.Point;
import java.util.ArrayList;

public class CellAnisotropy implements IAnisotropy {

	private double _dg;
	
	@Override
	public void setDegree(double dg) {
		_dg = dg;
	}
	
	public void getPhi() {
		throw new UnsupportedOperationException();
	}

	@Override
	public void culc(ArrayList<PhiObject> ls, int step, int br, Domain d, DomainDrawPanel ddp) {
		
		for(int i = 0; i < ls.size(); i++){
			ls.get(i).rotate(_dg);
		}
		
		int err = 0;
		DomainDrawPanel ldp = ddp; 
		//first Object
		boolean[] map = new boolean[ls.size()];	//карта размещенных объектов
		
		for(int t = 0; t  < map.length; t++)
			map[t] = false;
		
		boolean fst = false;
		ls.get(0).moveTo(br, br);
		while(ls.get(0).getIntPy() <= (d.getHeight() + br)){
			while(ls.get(0).getIntPx() <= (d.getWidth() + br)){
				ls.get(0).translate(step, 0);
				if(d.inside(ls.get(0), br)){
					break;
				}
			}
			if(d.inside(ls.get(0), br)){
				fst = true;
				break;
			}
			double l = GMath.length(br, 0, ls.get(0).getPx(), 0);
			ls.get(0).translate(-l, 0);
			ls.get(0).translate(0, step);	
		}
		if (fst)
			map[0] = true;
		else{
			ls.get(0).setWork(false);
			err++;
		}
			
		
		
		for(int i = 1; i < ls.size(); i++){		//перебор всех объектов
			ArrayList<Point> plt = new ArrayList<Point>();		//массив оптимальных точкек
			ls.get(i).moveTo(br, br);		//перемещение текущего объекта в начало координат
			
			
			while(ls.get(i).getIntPy() <= (d.getHeight() + br)){	//обход объекта по у
				boolean ints = false;		//оптимальная точка найдена на данном проходе
				
				while(ls.get(i).getIntPx() <= (d.getWidth() + br)){		//обход объекта по х
					
					ls.get(i).translate(step, 0);		//перемещение объекта на шаг вправо
					
					if(d.inside(ls.get(i), br)){		//объект полностью находится в области размещения
	
						
						
						
						
						int c = 0;

						for(int j = 0; j < ls.size(); j++){		
							if(j != i && map[j]){			
								c++;
							}
						}
						boolean[] frag = new boolean[c];
					
						
						
						c = 0;
						for(int j = 0; j < ls.size(); j++){		//проверка пересечения с другими объектами
							if(j != i && map[j]){			//чтобы не взаимного пресечения
								
								
								if(!GMath.smart_intersect(ls.get(i), ls.get(j))) {
									frag[c] = true; 	//пересечений с другими объектами нет
								}
								c++;
							}
						}
						
						int cnt = 0;
						for(int h = 0; h < frag.length; h++){
							if(!frag[h]) cnt++;
						}
						
						if (cnt == 0){
							ints = true; //!
						}
						
						
						
						
						
						
					}
					
					if(ints){			//Типа щасливая точка
						Point rtfm = new Point(ls.get(i).getIntPx(), ls.get(i).getIntPy());	//
						plt.add(rtfm);	//
						break;	//
					}
				}
				double l = GMath.length(br, 0, ls.get(i).getPx(), 0);	//
				ls.get(i).translate(-l, 0);		//
				ls.get(i).translate(0, step);	//
			}
			
			System.out.println(i + " : " + plt.size());
			if(plt.size() > 0){
				Point happy = new Point(zompacto(plt, br).x, zompacto(plt, br).y);		//
				ls.get(i).moveTo(happy.x, happy.y);
				map[i] = true; ////
			}
			else
			{
				ls.get(i).setWork(false);
				err++;
			}
			
		}
		
		ldp.addnotset(err);
	}
	
	private Point zompacto(ArrayList<Point> s, int br){
		Point o = new Point(br, br);
		double[] lgs = new double[s.size()];
		
		for(int i = 0; i < s.size(); i++){
			lgs[i] = GMath.length(o.x, o.y, s.get(i).x, s.get(i).y);
		}
			
		double min = lgs[0];
		int uuuu = 0;
		for(int i = 0; i < s.size(); i++){
			if(min > lgs[i]){
				min = lgs[i];
				uuuu = i;
			}
		}
		
		return s.get(uuuu);
	}
	
}